//<FILENAME>StringTable.cpp</FILENAME>
//<AUTHOR>WangLiLiang</AUTHOR>
//<DATE>2012.04.04</DATE>
//<TYPE>CPP PROGRAM CLASS</TYPE>

#include <cassert>
#include "StringTable.h"
using namespace Wll;
using namespace std;

//获取字符串注册的索引，如果字符串不存在，首先注册，然后返回新注册的索引值
int StringTable::GetIndexByName(const string& name)
{
	MapType::const_iterator i = this->name2index_table.find(name);
	if(i == this->name2index_table.end())
	{
		//没有注册，现在注册
		size_t index = this->index2name_table.size();
		this->index2name_table.push_back(name);
		this->name2index_table[name]=index;
		return index;
	}
	else
	{
		return i->second;
	}
}

//根据先前注册时分配的索引值获取字符串
const string& StringTable::GetNameByIndex(int index)
{
	if(index<0 || index >=this->index2name_table.size()) 
		throw IndexOutOfBoundaryException();

	return this->index2name_table[index];
}

void StringTable::Save(std::ostream& o) const
{
    o << "index2name_table:" << "\t" << this->index2name_table.size() << endl;
    int n = 0;
    for (vector<string>::const_iterator i = this->index2name_table.begin(); i != this->index2name_table.end(); ++i)
    {
        o << n++ << "\t" << *i << endl;
    }

    o << "name2index_table:" << "\t" << this->name2index_table.size() << endl;
    for (map<string,int>::const_iterator i = this->name2index_table.begin(); i != this->name2index_table.end(); ++i)
    {
        o << i->first << "\t" << i->second <<endl;
    }
}

void StringTable::Load(std::istream& i)
{
    string s;
    i >> s;
    assert(s == "index2name_table:");
    int n;
    i >> n;
    this->index2name_table.clear();
    for (int j = 0; j < n; j++)
    {
        int index = 0;
        i >> index;
        assert(j == index);

        string name;
        i >> name;
        this->index2name_table.push_back(name);
    }

    i >> s;
    assert(s == "name2index_table:");
    i >> n;
    this->name2index_table.clear();
    for (int j = 0; j < n; j++)
    {
        string name;
        int index = 0;
        i >> name;
        i >> index;
        this->name2index_table[name] = index;
    }
    assert(this->name2index_table.size() == n);
}
